package com.didi.gulimall.auth.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.didi.gulimall.api.MemberApiService;
import com.didi.gulimall.api.ThirdPartyApiService;
import com.didi.gulimall.auth.service.AuthMemberService;
import com.didi.gulimall.auth.vo.UserLoginVo;
import com.didi.gulimall.auth.vo.UserRegistVo;
import com.didi.gulimall.common.constant.AuthServerConstant;
import com.didi.gulimall.common.constant.BizCodeEnume;
import com.didi.gulimall.common.constant.SystemConstant;
import com.didi.gulimall.common.constant.ThirdPartyConstant;
import com.didi.gulimall.common.to.MemberResponseVo;
import com.didi.gulimall.common.utils.R;
import com.didi.gulimall.common.utils.ValidateCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 10626
 */
@Slf4j
@Service
public class AuthMemberServiceImpl implements AuthMemberService {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ThirdPartyApiService thirdPartyApiService;

    @Autowired
    private MemberApiService memberApiService;

    @Value("${gulimall.reg}")
    private String regHtml;

    @Value("${gulimall.home}")
    private String homeHtml;

    @Value("${gulimall.login}")
    private String loginHtml;

    @Override
    public R sendCode(String phone) {
        String s = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone);
        if (StringUtils.isNotBlank(s)) {
            long dataTime = Long.parseLong(s.substring(s.indexOf("_") + 1, s.length()));
            long difference = System.currentTimeMillis() - dataTime;
            if (difference < ThirdPartyConstant.SMS_TIMEOUT) {
                return R.error(BizCodeEnume.FREQUENT_OPERATION.getMsg());
            }
        }
        String data = ValidateCode.createData();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", data);
        R r = thirdPartyApiService.sendCode(phone, jsonObject.toJSONString());
        if (r.getCode() != 0) {
            return r;
        }
        data = data + "_" + System.currentTimeMillis();
        redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone, data, 10, TimeUnit.MINUTES);
        return r;
    }

    @Override
    public String registered(UserRegistVo userRegistVo, RedirectAttributes redirectAttributes) {
        Map<String, String> map = new HashMap<>();
        String code = userRegistVo.getCode();
        String s = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + userRegistVo.getPhone());
        if (StringUtils.isNotBlank(s)) {

            String verificationCode = s.substring(0, s.indexOf("_"));
            if (code.equals(verificationCode)) {
                if (!code.equals("650789")) {
                    redisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX + userRegistVo.getPhone());
                }
                R r = memberApiService.registered(userRegistVo);
                if (r.getCode() != 0) {
                    map.put(SystemConstant.MSG, r.getData(SystemConstant.MSG, new TypeReference<String>() {
                    }));
                    redirectAttributes.addFlashAttribute(SystemConstant.ERRORS, map);
                    return "redirect:" + regHtml;
                }

                return "redirect:" + loginHtml;
            } else {
                // 验证码不一致
                map.put("code", BizCodeEnume.INCORRECT_VERIFICATION_CODE.getMsg());
                redirectAttributes.addFlashAttribute(SystemConstant.ERRORS, map);
                return "redirect:" + regHtml;
            }
        } else {
            // 过期
            map.put("code", BizCodeEnume.VERIFICATION_CODE_EXPIRED.getMsg());
            redirectAttributes.addFlashAttribute(SystemConstant.ERRORS, map);
            return "redirect:" + regHtml;
        }
    }

    @Override
    public String login(UserLoginVo userLoginVo, RedirectAttributes redirectAttributes, HttpSession session) {
        R r = memberApiService.login(userLoginVo);
        if (r.getCode() != 0) {
            String msg = r.getData(SystemConstant.MSG, new TypeReference<String>() {
            });
            redirectAttributes.addFlashAttribute(SystemConstant.ERRORS, msg);
            return "redirect:" + loginHtml;
        }
        MemberResponseVo user = r.getData("user", new TypeReference<MemberResponseVo>() {
        });
        session.setAttribute(AuthServerConstant.LOGIN_USER, user);
        return "redirect:" + homeHtml;
    }
}
